package main

import (
	"fmt"
	"runtime"
	"time"
)

func main() {
	//i := make(chan int) //定义一个在main go程和子go程之间的管道
	//
	//go func() {
	//	defer fmt.Println("子go程结束")
	//	fmt.Println("子go程正在运行")
	//	i <- 666 // 将666发送到管道
	//}()
	//
	//num := <-i //从i 中接收数据，并赋值到num
	//fmt.Println(num)
	//fmt.Println("main go 程结束")
	// noBufferedChan()
	bufferedChan()
	for {

	}
}

/**
在你的代码中，主goroutine（main函数）会等待2秒钟，然后从无缓冲的通道中接收3个整数。在这段时间内，子goroutine正在运行。问题的关键在于主goroutine在子goroutine结束之前退出，这会导致子goroutine被强制终止，从而导致defer语句没有执行。

这是因为在Go语言中，当主goroutine（即main函数所在的goroutine）结束时，整个程序也会退出。即使子goroutine还没有完成它的任务，程序也会终止，因此子goroutine的defer语句也不会执行。
*/

// 了解一下无缓冲的channel执行流程
func noBufferedChan() {
	c := make(chan int, 0)

	fmt.Printf("len(c)=%d,cap(c)=%d \n", len(c), cap(c))

	go func() {
		defer fmt.Println("子go程结束")

		for i := 0; i < 3; i++ {
			c <- i
			fmt.Printf("子go程正在运行[%d]: len(c)=%d, cap(c)=%d\n", i, len(c), cap(c))
		}
		runtime.Goexit()
	}()

	time.Sleep(time.Second * 2)

	for i := 0; i < 3; i++ {
		num := <-c
		fmt.Println("num = ", num)
	}
	fmt.Println("main go程结束")
}

// 了解一下有缓冲的channle执行流程，关键在于达到最大容量了会阻塞，
func bufferedChan() {
	c := make(chan int, 3)
	//内置函数 len 返回未被读取的缓冲元素数量， cap 返回缓冲区大小
	fmt.Printf("len(c)=%d,cap(c)=%d\n", len(c), cap(c))

	go func() {
		defer fmt.Println("子go程结束")
		for i := 0; i < 5; i++ {
			c <- i
			fmt.Printf("子go程正在运行[%d]: len(c)=%d, cap(c)=%d\n", i, len(c), cap(c))
		}
	}()

	time.Sleep(10 * time.Second)
	for i := 0; i < 3; i++ {
		num := <-c //从管道里接收数据
		fmt.Println("num = ", num)
	}
	fmt.Println("main go 结束")
}
